package com.jerry.scan.utils;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jerry.jmx.utils.JMXConn;
import com.jerry.utils.str.Jutils;
import com.jerry.utils.zbx.ZBX;

public class ScanIP implements Runnable {

	private static final Logger log = LoggerFactory.getLogger(ScanIP.class);
	private static int miniport = Integer.parseInt(Jutils.getProperty("scan.miniport"));
	private static int maxport = Integer.parseInt(Jutils.getProperty("scan.maxport"));
	private static int threadcnt = Integer.parseInt(Jutils.getProperty("scan.threadcnt"));
	private static int timeout = Integer.parseInt(Jutils.getProperty("scan.timeout"));
	private static String host = ""; // 扫描Ip地址

	public static void setHost(String scanIP) {
		ScanIP.host = scanIP;
	}

	public static String getHost() {
		return host;
	}

	/**
	 * 数据执行
	 * 
	 * @throws InterruptedException
	 * @throws IOException
	 */
	public static void doScan(String scanIP) throws InterruptedException, IOException {

		ScanIP.setHost(scanIP);
		int totalPortCnt = maxport - miniport;// 待处理端口数
		int threadDealCnt = totalPortCnt / threadcnt;// 每一个线程处理的数目
		int lastThreadDealCnt = totalPortCnt % threadcnt;// 最后一个线程处理数目
		log.warn("待处理数" + totalPortCnt);
		log.warn("每一个线程处理的数目" + threadDealCnt);
		log.warn("余数为 " + lastThreadDealCnt);
		log.warn("线程数：" + threadcnt);
		CountDownLatch countDownLatch = new CountDownLatch(threadcnt);

		int moreLastCnt = miniport - 1;
		// 线程分发
		for (int threadIndex = 1; threadIndex <= threadcnt; threadIndex++) {
			int startPort = 0;
			int endPort = 0;
			// 余数分布到每一个线程里面去处理
			startPort = moreLastCnt + 1;
			if (threadIndex <= lastThreadDealCnt && 0 != lastThreadDealCnt) {
				endPort = startPort + threadDealCnt;
			} else {
				endPort = startPort + (threadDealCnt - 1);
			}
			moreLastCnt = endPort;
			new ScanIP(startPort, endPort, timeout, countDownLatch).start();
		}
		countDownLatch.await();

		log.warn(ScanIP.getHost() + " is scan end!");

	}

	// 主要业务处理逻辑
	private int begIndex;
	private int endIndex;
	private Thread thread;
	private CountDownLatch countDownLatch;

	public ScanIP(int begIndex, int endIndex, int timeout, CountDownLatch countDownLatch) {
		super();
		this.begIndex = begIndex;
		this.endIndex = endIndex;
		this.countDownLatch = countDownLatch;
		thread = new Thread(this);

	}

	/**
	 * 线程启动
	 */
	public ScanIP start() {
		thread.start();
		log.warn(thread.getName() + "deal [" + ScanIP.getHost() + ":" + this.begIndex + "----" + this.endIndex + "]"
				+ "[" + (this.endIndex - this.begIndex + 1) + "]");
		return this;
	}

	// 线程执行
	@Override
	public void run() {

		for (int i = begIndex; i <= endIndex; i++) {
			log.debug("now is " + ScanIP.getHost() + ":" + i);

			if (scan(ScanIP.getHost(), i, timeout)) {
				log.debug("the port is :" + ScanIP.getHost() + ":" + i + "checkout");
				if (JMXConn.checkJMX(ScanIP.getHost(), i)) {
					boolean ch = ZBX.createHost(host, i);
					log.debug("check zbx create host" + ch);
					if (ch) {
						log.debug("create host: " + host + " port: " + i);
					}

				}
			}

		}
		log.debug("thread has deal finished " + thread.getName());
		countDownLatch.countDown();

	}

	// 端口扫描
	public static boolean scan(String scanIP, int port, int timeOut) {
		boolean flag = false;
		Socket socket = null;
		try {
			socket = new Socket();
			socket.connect(new InetSocketAddress(scanIP, port), timeOut);
			socket.setSoTimeout(timeOut);
			flag = true;
		} catch (IOException e) {
		} finally {
			try {
				if (socket != null) {
					socket.close();
				}
			} catch (Exception e) {
			}
		}
		return flag;
	}

	public static void main(String[] args) {
//	  try {
//		this.doScan("172.16.12.128");
//	} catch (InterruptedException e) {
//		// TODO Auto-generated catch block
//		e.printStackTrace();
//	} catch (IOException e) {
//		// TODO Auto-generated catch block
//		e.printStackTrace();
//	}

	}
}